﻿// <copyright file="Tag.cs" company="Signal Processing Lab, Wuhan University">
// Copyright (c) 2009-2010 All Right Reserved
// </copyright>
// <author>Xinping Deng</author>
// <email>dentoby@gmail.com</email>
// <date>2010-4</date>
// <summary>This is part of Image.NET project.</summary>

namespace SPLWHU.Core
{
    using System;
    using System.Collections.Generic;

    /// <summary>
    /// A class used to display a value or parse a value from the text.
    /// It can be employed to show and get a value in GUI interaction and other data exchange situation.
    /// </summary>
    public abstract class Tag
    {
        /// <summary>
        /// Indicating whether the value can be modified or not.
        /// </summary>
        private bool readOnly = false;

        /// <summary>
        /// The name of this tag.
        /// </summary>
        private string name = string.Empty;

        /// <summary>
        /// This event fires when [read only changed].
        /// </summary>
        public event ReadOnlyChanged ReadOnlyChanged;

        /// <summary>
        /// Occurs when the value changed.
        /// </summary>
        public event ValueChanged ValueChanged;
        
        /// <summary>
        /// Gets or sets a value indicating whether the value is read only or not.
        /// </summary>
        public virtual bool ReadOnly
        {
            get 
            { 
                return this.readOnly; 
            }

            set
            {
                // the readonly changed.
                if (this.readOnly != value)
                {
                    this.readOnly = value;

                    // fires the event.
                    if (this.ReadOnlyChanged != null)
                    {
                        this.ReadOnlyChanged(this, new ReadOnlyChangedArgs(value));
                    }
                }
            }
        }

        /// <summary>
        /// Gets or sets the name of this tag.
        /// </summary>
        /// <value>The name of this tag.</value>
        public virtual string Name
        {
            get 
            { 
                return this.name; 
            }

            set 
            {
                this.name = value; 
            }
        }

        /// <summary>
        /// Gets the type of value stored in this tag.
        /// </summary>
        public abstract Type ValueType { get; }

        /// <summary>
        /// Converts the value of this instance to text.
        /// </summary>
        /// <returns>Converted text representing the value.</returns>
        public abstract string ValueToText();

        /// <summary>
        /// Parses the value of this instance from text.
        /// </summary>
        /// <param name="text">The text to be parsed to generate value.</param>
        public abstract void ValueFromText(string text);

        /// <summary>
        /// Reset the value to default value.
        /// </summary>
        public abstract void ResetValue();

        /// <summary>
        /// Retrives the value in this tag.
        /// </summary>
        /// <returns>The value stored in this tag.</returns>
        public abstract object GetValue();

        /// <summary>
        /// Fires the event value changed.
        /// </summary>
        /// <param name="previous">The previous value.</param>
        /// <param name="newValue">The new value.</param>
        protected virtual void FireValueChanged(object previous, object newValue)
        {
            if (this.ValueChanged != null)
            {
                this.ValueChanged(this, new ValueChangedArgs(previous, newValue));
            }
        }
    }
}
